package com.qsw.paper.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qsw.paper.constant.MessageConstants;
import com.qsw.paper.constant.StatusConstants;
import com.qsw.paper.exception.ObjectException;
import com.qsw.paper.mapper.AdvisorsMapper;
import com.qsw.paper.mapper.StudentsMapper;
import com.qsw.paper.mapper.UsersMapper;
import com.qsw.paper.pojo.dto.UserChangPaDto;
import com.qsw.paper.pojo.dto.UserLoginDto;
import com.qsw.paper.pojo.dto.UserUpdateDto;
import com.qsw.paper.pojo.entity.Advisors;
import com.qsw.paper.pojo.entity.Students;
import com.qsw.paper.pojo.entity.Users;
import com.qsw.paper.pojo.vo.UserVO;
import com.qsw.paper.service.IUsersService;
import com.qsw.paper.utils.ThreadLocalUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.util.Objects;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author qsw
 * @since 2024-11-16
 */
@RequiredArgsConstructor
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {
    private final AdvisorsMapper advisorsMapper;
    private final StudentsMapper studentsMapper;

    /**
     * 用户登录
     *
     * @param loginDto dto
     * @return user
     */
    @Override
    public Users login(UserLoginDto loginDto) {
        Users user = baseMapper.selectOne(new LambdaQueryWrapper<Users>()
                .eq(Users::getUsername, loginDto.getUsername()
                .trim().replace("--","")));
        if (user == null) {
            throw new ObjectException(MessageConstants.USER_NULL);
        }
        String password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());
        if (!user.getPassword().equals(password)) {
            throw new ObjectException(MessageConstants.USER_PASSWORD_ERR);
        }
        if (!user.getStatus().equals(StatusConstants.ONE)) {
            throw new ObjectException(MessageConstants.ACCOUNT_LOCKED);
        }
        return user;
    }

    /**
     * 用户修改个人信息
     *
     * @param userDto dto
     */
    @Override
    public void updateById(@NotNull UserUpdateDto userDto) {
        userDto.setUserId(userDto.getUserId() == null ? ThreadLocalUtil.getId() : userDto.getUserId());
        baseMapper.updateById(BeanUtil.copyProperties(userDto, Users.class));
    }

    /**
     * 用户修改密码
     *
     * @param paDto dto
     */
    @Transactional
    @Override
    public void updatePassword(@NotNull UserChangPaDto paDto) {
        // 获取当前用户
        Integer userId = ThreadLocalUtil.getId();
        Users users = baseMapper.selectById(userId);
        if (users == null) {
            throw new ObjectException(MessageConstants.USER_NOT_FOUND);
        }
        // 校验旧密码
        String encryptedOldPassword = encryptPassword(paDto.getOldPassword());
        if (!users.getPassword().equals(encryptedOldPassword)) {
            throw new ObjectException(MessageConstants.PASSWORD_ERR);
        }

        // 校验新旧密码是否一致
        String encryptedNewPassword = encryptPassword(paDto.getNewPassword());
        if (users.getPassword().equals(encryptedNewPassword)) {
            throw new ObjectException(MessageConstants.PASSWORD_IDENTICAL);
        }

        // 更新密码
        int updated = baseMapper.update(new LambdaUpdateWrapper<Users>().set(Users::getPassword, encryptedNewPassword).eq(Users::getUserId, userId));

        if (updated <= 0) {
            throw new ObjectException(MessageConstants.PASSWORD_UPDATE_FAIL);
        }
    }

    /**
     * 获取用户信息
     *
     * @return 用户实体
     */
    @Override
    public UserVO getUserDetailById() {
        Integer id = ThreadLocalUtil.getId();
        // 查询用户基本信息
        Users user = baseMapper.selectById(id);
        if (user == null) {
            throw new ObjectException(MessageConstants.USER_NULL);
        }

        // 转换为VO对象
        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);

        // 根据角色查询详细信息
        switch (user.getRole()) {
            case StatusConstants.ONE -> { // 学生角色
                Students students = studentsMapper.selectOne(new LambdaQueryWrapper<Students>().eq(Students::getUserId, user.getUserId()));
                if (students != null) {
                    userVO.setInfo(students);
                }
            }
            case StatusConstants.TWO -> { // 导师角色
                Advisors advisors = advisorsMapper.selectOne(new LambdaQueryWrapper<Advisors>().eq(Advisors::getUserId, user.getUserId()));
                if (advisors != null) {
                    userVO.setInfo(advisors);
                }
            }
            default -> // 未知角色
                    throw new ObjectException(MessageConstants.UNKNOWN_ROLE + ": " + user.getRole());
        }

        return userVO;
    }


    private @NotNull String encryptPassword(@NotNull String password) {
        return DigestUtils.md5DigestAsHex(password.getBytes());
    }

}
